import * as Blockly from 'blockly/core'

const json = {
  type: 'request_model',
  // 业务接口参数 %4
  'message0': 'request请求 %1 业务模型编码 %2 业务服务编码 %3 ',
  args0: [
    {
      'type': 'input_dummy'
    },
    {
      'type': 'input_value',
      'name': 'PARAM_MODEL',
      'check': 'String'
    },
    {
      'type': 'input_value',
      'name': 'PARAM_API',
      'check': 'String'
    }
    // {
    //   'type': 'input_value',
    //   'name': 'PARAM_OPTIONS'
    // }
  ],
  style: 'action_blocks',
  'helpUrl': '',
  'tooltip': 'request 用来向后端发起请求，返回promise',
  // 'inputsInline': false,
  'previousStatement': null,
  'nextStatement': null,
  'mutator': 'request_mutator'
}

// 创建积木
Blockly.Blocks['request_model'] = {
  init: function () {
    this.jsonInit(json)
  }
}

const mixinObj = {
  /**
   * Create XML to represent number of text inputs.
   * @return {!Element} XML storage element.
   * @this {Blockly.Block}
   */
  mutationToDom: function () {
    var container = Blockly.utils.xml.createElement('mutation')
    container.setAttribute('param', this.paramCount_)
    container.setAttribute('success', this.successCount_)
    container.setAttribute('error', this.errorCount_)
    return container
  },
  /**
   * Parse XML to restore the text inputs.
   * @param {!Element} xmlElement XML storage element.
   * @this {Blockly.Block}
   */
  domToMutation: function (xmlElement) {
    this.paramCount_ = parseInt(xmlElement.getAttribute('param'), 10) || 0
    this.successCount_ = parseInt(xmlElement.getAttribute('success'), 10) || 0
    this.errorCount_ = parseInt(xmlElement.getAttribute('error'), 10) || 0
    this.updateShape_()
  },
  /**
   * Populate the mutator's dialog with this block's components.
   * @param {!Blockly.Workspace} workspace Mutator's workspace.
   * @return {!Blockly.Block} Root block in mutator.
   * @this {Blockly.Block}
   */
  // 打开变异器弹窗的行为
  // decompose: function (workspace) {
  //   console.log('decompose')
  //   var containerBlock = workspace.newBlock('text_create_join_container')
  //   containerBlock.initSvg()
  //   // text_create_join_container 内含 input_statement Stack input
  //   var connection = containerBlock.getInput('STACK').connection
  //   if (this.successCount_) {
  //     var openBlock = workspace.newBlock('success_func')
  //     openBlock.initSvg()
  //     connection.connect(openBlock.previousConnection)
  //     connection = openBlock.nextConnection
  //   }
  //   if (this.errorCount_) {
  //     var closeBlock = workspace.newBlock('error_func')
  //     closeBlock.initSvg()
  //     connection.connect(closeBlock.previousConnection)
  //     connection = closeBlock.nextConnection
  //   }
  //   return containerBlock
  // },
  /**
   * Reconfigure this block based on the mutator dialog's components.
   * @param {!Blockly.Block} containerBlock Root block in mutator.
   * @this {Blockly.Block}
   */
  // 变异器器弹窗的行为配置  并调用updateShape展示积木块
  // compose: function (containerBlock) {
  //   this.successCount_ = 0
  //   this.errorCount_ = 0
  //   var itemBlock = containerBlock.getInputTargetBlock('STACK')
  //   // Count number of inputs.
  //   // var connections = []
  //   while (itemBlock) {
  //     // connections.push(itemBlock.valueConnection_)
  //     if (itemBlock.type === 'success_func') {
  //       this.successCount_++
  //     }
  //     if (itemBlock.type === 'error_func') {
  //       this.errorCount_++
  //     }
  //     itemBlock = itemBlock.nextConnection &&
  //       itemBlock.nextConnection.targetBlock()
  //   }
  //   this.updateShape_()
  // },
  /**
   * Store pointers to any connected child blocks.
   * @param {!Blockly.Block} containerBlock Root block in mutator.
   * @this {Blockly.Block}
   */
  // saveConnections: function (containerBlock) {
  //   var itemBlock = containerBlock.getInputTargetBlock('STACK')
  //   var clauseBlock = itemBlock?.nextConnection?.targetBlock()
  //   while (clauseBlock) {
  //     switch (clauseBlock.type) {
  //     case 'success_func':
  //       var inputDo = this.getInput('success_func')
  //       clauseBlock.valueConnection_ =
  //           inputDo && inputDo.connection.targetConnection
  //       break
  //     case 'error_func':
  //       const inputDo1 = this.getInput('error_func')
  //       clauseBlock.valueConnection_ =
  //           inputDo1 && inputDo1.connection.targetConnection
  //       break
  //     default:
  //       throw TypeError('Unknown block type: ' + clauseBlock.type)
  //     }
  //     clauseBlock = clauseBlock.nextConnection &&
  //       clauseBlock.nextConnection.targetBlock()
  //   }
  // },
  /**
   * Modify this block to have the correct number of inputs.
   * @private
   * @this {Blockly.Block}
   */
  updateShape_: function () {
    if (this.paramCount_) {
      if (!this.getInput('PARAM_OPTIONS')) {
        const input = this.appendValueInput('PARAM_OPTIONS').setCheck('Object')
        input.appendField('请求参数')
      }
    } else {
      if (this.getInput('PARAM_OPTIONS')) {
        this.removeInput('PARAM_OPTIONS')
      }
    }

    if (this.successCount_) {
      if (!this.getInput('success_func')) {
        this.appendValueInput('success_func').setCheck('callback_function_expression')
          .appendField('请求成功回调函数')
      }
    } else {
      if (this.getInput('success_func')) {
        this.removeInput('success_func')
      }
    }
    if (this.errorCount_) {
      if (!this.getInput('error_func')) {
        this.appendValueInput('error_func').setCheck('callback_function_expression')
          .appendField('请求失败回调函数')
      }
    } else {
      if (this.getInput('error_func')) {
        this.removeInput('error_func')
      }
    }
  }
}

const helpFun = function () {
  this.paramCount_ = 1
  this.successCount_ = 1
  this.errorCount_ = 1
  this.updateShape_()
}

Blockly.Extensions.registerMutator('request_mutator',
  mixinObj, helpFun,
  ['success_func', 'error_func'])

const successJson =
  {
    'type': 'success_func',
    'message0': '请求成功回调 %1',
    'args0': [
      {
        'type': 'input_value',
        'name': 'SUCCESS'
      }
    ],
    style: 'action_blocks',
    'previousStatement': null,
    'nextStatement': null,
    inputsInline: false,
    'check': 'String',
    'tooltip': '设置请求成功回调函数'
  }
// 创建积木
Blockly.Blocks['success_func'] = {
  init: function () {
    this.jsonInit(successJson)
  }
}

const errorJson =
  {
    'type': 'success_func',
    'message0': '请求失败回调 %1',
    'args0': [
      {
        'type': 'input_value',
        'name': 'SUCCESS'
      }
    ],
    style: 'action_blocks',
    'previousStatement': null,
    'nextStatement': null,
    inputsInline: false,
    'check': 'String',
    'tooltip': '设置请求失败回调函数'
  }
// 创建积木
Blockly.Blocks['error_func'] = {
  init: function () {
    this.jsonInit(errorJson)
  }
}

Blockly.JavaScript['request_model'] = function (block) {
  const modelKey = Blockly.JavaScript.valueToCode(block, 'PARAM_MODEL',
    Blockly.JavaScript.ORDER_COMMA) || '\'\''
  const apiKey = Blockly.JavaScript.valueToCode(block, 'PARAM_API',
    Blockly.JavaScript.ORDER_COMMA) || '\'\''
  const options = Blockly.JavaScript.valueToCode(block, 'PARAM_OPTIONS',
    Blockly.JavaScript.ORDER_COMMA) || '{}'
  // 这里context需要转换吗
  let code = `context.request(${modelKey}, ${apiKey}, ${options}).then(`
  if (block.successCount_) {
    const onSuccess = Blockly.JavaScript.valueToCode(block, 'success_func',
      Blockly.JavaScript.ORDER_COMMA) || '(response) => {\n}'
    code = code + onSuccess + ','
  }
  if (block.errorCount_) {
    const onError = Blockly.JavaScript.valueToCode(block, 'error_func',
      Blockly.JavaScript.ORDER_COMMA) || '(error) => {}\n'
    code = code + onError
  }
  code = code + ')'
  return code + '\n'
}
